package com.charging.common.utils;


import com.charging.common.exception.BusinessException;
import com.charging.common.utils.sign.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Random;

public class XGSEncryptUtil {

    private static final Logger log = LoggerFactory.getLogger(XGSEncryptUtil.class);

    public static final String encrypt(String str) {

        String string_in = "YaNb8cKd1eJfOgZhViUjRkBl3mMnDoEpTqSr5sGtPuLv2w7xAyXzWIHQ94C6F0#$_@!~`%^&*()-+=[]{}'|?;:/,<>.\"\\ ";
        String string_out = " @!~`%^&*()-+=[]{}'|?;:/,<>._$#AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789\"\\";
        String outpass = "";
        try {
            if (str != null) {
                int offset = 0;
                Calendar calendar = Calendar.getInstance();
                int ss = calendar.get(Calendar.SECOND);
                offset = ss % 94;
                if (offset > 0)
                    offset = offset - 1;
                outpass = string_in.substring(offset, offset + 1);
                string_in = string_in + string_in;
                string_in = string_in.substring(offset, offset + 95);
                outpass = outpass + translate(str, string_in, string_out);
                outpass = strToAscStr(outpass, "-");
                return outpass;
            } else {
                return "";
            }
        } catch (Exception e) {
            return "";
        }
    }

    public static final String disencrypt(String str) {
        str = ascToStr(str, "-");
        String string_in = "YaNb8cKd1eJfOgZhViUjRkBl3mMnDoEpTqSr5sGtPuLv2w7xAyXzWIHQ94C6F0#$_@!~`%^&*()-+=[]{}'|?;:/,<>.\"\\ ";
        String string_out = " @!~`%^&*()-+=[]{}'|?;:/,<>._$#AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789\"\\";
        try {
            int offset = 0;
            char c = str.charAt(0);
            offset = string_in.indexOf(c);
            string_in = string_in + string_in;
            string_in = string_in.substring(offset, offset + 95);
            String s = str.substring(1);
            String inpass = translate(s, string_out, string_in);
            return inpass;
        } catch (Exception e) {
            return "";
        }
    }

    private static final String translate(String str, String string_in, String string_out) {

        char[] outc = new char[str.length()];
        for (int i = 0; i < str.length(); i++) {
            char c = str.charAt(i);
            int j = string_in.indexOf(c);
            outc[i] = string_out.charAt(j);

        }
        String outs = new String(outc);

        return outs;
    }

    private static String strToAscStr(String str, String splitStr) {
        String retStr = "";
        if (null == str) {
            return "";
        }
        byte[] byteArray = str.getBytes();
        for (int i = 0; i < byteArray.length; i++) {
            retStr += Integer.toHexString(byteArray[i]) + splitStr;
        }
        if (retStr.length() > splitStr.length()) {
            return retStr.substring(0, retStr.length() - splitStr.length());
        } else {
            return retStr;
        }
    }

    private static String ascToStr(String str, String split) {
        String retStr = "";
        if (null == str) {
            return retStr;
        }
        String[] strArray = str.split(split);
        if (null != strArray && 0 < strArray.length) {
            for (int i = 0; i < strArray.length; i++) {
                retStr += (char) Integer.parseInt(strArray[i], 16);
            }
        }
        return retStr;
    }


    /**
     * xgs带中文加密算法
     * @param Src 需要加密的字符串
     * @param Encrypt True为加密，False为解密
     * @param zKey 种子
     * @param baseFlag True为使用base64加密，False为不使用
     * @return
     */
    public static String EncryptEx(String Src, Boolean Encrypt, String zKey,Boolean baseFlag) {
        String strEnc = "UTF-8";

        if(StringUtils.isEmpty(Src)){
            return "";
        }

        int KeyLen, KeyPos, offset, SrcPos, SrcAsc, TmpSrcAsc, Range, hexTemp;
        KeyLen = zKey.length();
        if (KeyLen == 0) {
            zKey = "Hello";
        }
        KeyPos = 0;
        Range = 256;
        if (Encrypt) {
            try {
                if(baseFlag){
                    //Base64编码
                    Src = Base64.encode(Src.getBytes(strEnc));
                }
                String Desc = "";
                String sTemp = "";
                Random rd = new Random(Range);
                offset = rd.nextInt(255);
                Desc = String.format("%02x", offset);

                byte[] chrSrc = new byte[0];
                byte[] bytezKey;
                char[] chrzKey = new char[0];
                try {
                    chrSrc = Src.getBytes(Charset.forName(strEnc));
                    bytezKey = zKey.getBytes(Charset.forName(strEnc));
                    chrzKey = new String(bytezKey, Charset.forName(strEnc)).toCharArray();
                } catch (Exception e) {
                    e.printStackTrace();
                }

                for (SrcPos = 1; SrcPos <= chrSrc.length; SrcPos++) {
                    SrcAsc = (chrSrc[SrcPos - 1] + offset) % 255;
                    SrcAsc = SrcAsc ^ chrzKey[KeyPos];
                    if (KeyPos < KeyLen - 1) {
                        KeyPos++;
                    } else {
                        KeyPos = 0;
                    }
                    Desc += String.format("%02x", SrcAsc);
                    offset = SrcAsc;
                }


                sTemp = "";
                for (SrcPos = 1; SrcPos <= Desc.length() / 2; SrcPos++) {
                    sTemp = sTemp + Desc.substring(Desc.length() - (SrcPos), Desc.length() - (SrcPos) + 1) + Desc.substring(SrcPos - 1, SrcPos);
                }

                hexTemp = 0;
                for (SrcPos = 0; SrcPos <= sTemp.length() / 2 - 1; SrcPos++) {
                    hexTemp = hexTemp ^ Integer.parseInt(sTemp.substring(SrcPos * 2, SrcPos * 2 + 2), 16);
                }

                sTemp = String.format("%02x", hexTemp) + sTemp;

                Desc = sTemp.toUpperCase();
                return Desc;
            } catch (Exception e) {
                //e.printStackTrace();
                log.error("解码异常："+e.toString());
                throw new BusinessException("加密异常");
            }
        } else {
            try {
                List<Byte> listDesc = new ArrayList<>();
                //listDesc.clear();

                hexTemp = 0;
                for (SrcPos = 0; SrcPos < Src.length() / 2 - 1; SrcPos++) {
                    hexTemp = hexTemp ^ Integer.parseInt(Src.substring(SrcPos * 2 + 2, SrcPos * 2 + 2 + 2), 16);
                }

                if (!(Src.substring(0, 2)).equalsIgnoreCase(String.format("%02x", hexTemp))) {
                    return "";
                }

                String sTemp = "";
                for (SrcPos = Src.length() / 2 - 1; SrcPos >= 1; SrcPos--) {
                    sTemp = Src.substring(SrcPos * 2 + 1, SrcPos * 2 + 1 + 1) + sTemp + Src.substring(SrcPos * 2, SrcPos * 2 + 1);
                }

                offset = Integer.parseInt(sTemp.substring(0, 2), 16);

                byte[] bytezKey;
                char[] chrzKey = new char[0];
                try {
                    bytezKey = zKey.getBytes(Charset.forName(strEnc));
                    chrzKey = new String(bytezKey, Charset.forName(strEnc)).toCharArray();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                SrcPos = 2;
                do {
                    SrcAsc = Integer.parseInt(sTemp.substring(SrcPos, SrcPos + 2), 16);
                    TmpSrcAsc = SrcAsc ^ chrzKey[KeyPos];
                    if (KeyPos < KeyLen - 1) {
                        KeyPos++;
                    } else {
                        KeyPos = 0;
                    }
                    if (TmpSrcAsc <= offset) {
                        TmpSrcAsc = 255 + TmpSrcAsc - offset;
                    } else {
                        TmpSrcAsc = TmpSrcAsc - offset;
                    }
                    listDesc.add((byte) TmpSrcAsc);
                    offset = SrcAsc;
                    SrcPos = SrcPos + 2;
                }
                while (SrcPos < sTemp.length());


                byte[] byteArrDesc = new byte[listDesc.size()]; // 将 List 转换为 byte 数组
                for (int i = 0; i < listDesc.size(); i++) {
                    byteArrDesc[i] = listDesc.get(i);
                }

                //String strDesc = new String(byteArrDesc, strEnc); // 使用 String 的 getBytes 方法进行转换
                String strDesc = new String(byteArrDesc, Charset.forName(strEnc));

                if(baseFlag){
                    //Base64解码
                    strDesc = new String(Base64.decode(strDesc),Charset.forName(strEnc));
                }

                return strDesc;
            } catch (Exception e) {
                //e.printStackTrace();
                log.error("解码异常："+e.toString());
                throw new BusinessException("解码异常");
            }
        }
    }

    public static void main(String args[]) {
        //System.out.println(String.format("%010d", 73010100));

        //System.out.println(Md5Utils.hash("111"));
        //System.out.println(Md5Utils.md5("698D51A19D8A121CE581499D7B701668"));
//       System.out.println(XGSEncryptUtil.encrypt("Xgssoft.xa.038"));
       //System.out.println(XGSEncryptUtil.encrypt("111"));
       //String json = "[{\"taskid\":1,\"taskname\":\"张三\"}]";
       //System.out.println("加密"+XGSEncryptUtil.EncryptExBase64(json, true, "xgssoft"));
       //System.out.println("加密"+XGSEncryptUtil.EncryptEx("111", true, "sxjk",false));
       //System.out.println("解密"+XGSEncryptUtil.EncryptEx("123", false, "sxjk",false));
    }

}
